package org.dromara.wms.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseService;
import org.dromara.mall.domain.MallMenu;
import org.dromara.sms4j.starter.utils.SpringUtil;
import org.dromara.wms.domain.*;
import org.dromara.wms.domain.productPC.Sku;
import org.dromara.wms.domain.productPC.SkuSpec;
import org.dromara.wms.domain.productPC.Spec;
import org.dromara.wms.domain.productPC.Value;
import org.dromara.wms.mapper.WmsProductMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 产品管理Service业务层处理
 *
 * @author wenrui
 * @date 2024-03-20
 */
@RequiredArgsConstructor
@Service
public class WmsProductServiceImpl extends BaseService {

  private final WmsProductMapper baseMapper;
  private final WmsProductOssServiceImpl ossService;

  public WmsGroupProductServiceImpl wmsGroupProductService() {
    return SpringUtil.getBean(WmsGroupProductServiceImpl.class);
  }

  /**
   * 查询产品管理
   */
  public WmsProduct queryById(Long id) {
    return baseMapper.selectById(id);
  }

  /**
   * 查询产品管理列表
   */
  public TableDataInfo<WmsProduct> queryPageList(WmsProduct bo, PageQuery pageQuery) {
    LambdaQueryWrapper<WmsProduct> lqw = buildQueryWrapper(bo);
    Page<WmsProduct> result = baseMapper.selectPage(pageQuery.build(), lqw);
    if (bo.getIds() != null && !bo.getIds().isEmpty()) {
      List<WmsProduct> records = result.getRecords();
      List<Long> parentIds = bo.getIds();
      records.removeIf(wmsProduct -> parentIds.contains(wmsProduct.getId()));
      result.setTotal(records.size());
    }
    return TableDataInfo.build(result);
  }

  /**
   * 查询产品管理列表
   */
  public List<WmsProduct> queryList(WmsProduct bo) {
    LambdaQueryWrapper<WmsProduct> lqw = buildQueryWrapper(bo);
    return baseMapper.selectList(lqw);
  }

  private LambdaQueryWrapper<WmsProduct> buildQueryWrapper(WmsProduct bo) {
    Map<String, Object> params = bo.getParams();
    LambdaQueryWrapper<WmsProduct> lqw = Wrappers.lambdaQuery();
    lqw.eq(StringUtils.isNotBlank(bo.getSku()), WmsProduct::getSku, bo.getSku());
    lqw.like(StringUtils.isNotBlank(bo.getName()), WmsProduct::getName, bo.getName());
    lqw.eq(bo.getIsStock() != null, WmsProduct::getIsStock, bo.getIsStock());
    lqw.eq(bo.getIsSales() != null, WmsProduct::getIsSales, bo.getIsSales());
    lqw.eq(bo.getIsMaterial() != null, WmsProduct::getIsMaterial, bo.getIsMaterial());
    lqw.eq(bo.getIsProduce() != null, WmsProduct::getIsProduce, bo.getIsProduce());
    lqw.eq(bo.getSpecification() != null, WmsProduct::getSpecification, bo.getSpecification());
    lqw.eq(bo.getMallMenuId() != null, WmsProduct::getMallMenuId, bo.getMallMenuId());
    lqw.eq(StringUtils.isNotBlank(bo.getTreeValue()), WmsProduct::getTreeValue, bo.getTreeValue());
    lqw.between(params.get("beginUpdateTime") != null && params.get("endUpdateTime") != null,
      WmsProduct::getUpdateTime, params.get("beginUpdateTime"), params.get("endUpdateTime"));
    lqw.orderByDesc(WmsProduct::getUpdateTime);
    return lqw;
  }

  /**
   * 新增产品管理
   */
  @Transactional(propagation = Propagation.REQUIRED)
  public Boolean insertByBo(WmsProduct bo) {
    validEntityBeforeSave(bo);
    Boolean res = baseMapper.insert(bo) > 0;
    for (WmsProductOss productOss : bo.getProductOss()) {
      productOss.setProductId(bo.getId());
    }
    insertProductOss(bo.getProductOss());
    return res;
  }

  /**
   * 新增产品图片
   */
  @Transactional(propagation = Propagation.REQUIRED)
  public void insertProductOss(List<WmsProductOss> ossList) {
    for (WmsProductOss wmsProductOss : ossList) {
      ossService.insertByBo(wmsProductOss);
    }
  }

  /**
   * 修改产品管理
   */
  @Transactional(propagation = Propagation.REQUIRED)
  public Boolean updateByBo(WmsProduct bo) {
    validEntityBeforeSave(bo);
    Long attrCount = wmsGroupProductService().getAttrCount(bo.getId());
    long count = bo.getAttrValue().chars()
      .filter(c -> c == '|')
      .count();
    if (attrCount == count){
      updateProductOss(bo);
      return baseMapper.updateById(bo) > 0;
    }else{
      throw new WmsStockService.emptyException(
        bo.getId()+bo.getName()+" 产品规格与对应产品组不匹配！");
    }
  }

  @Transactional(propagation = Propagation.REQUIRED)
  public void updateProductOss(WmsProduct productBo) {
    List<WmsProductOss> productOss = productBo.getProductOss();
    List<WmsProductOss> wmsProductOssList =  ossService.queryById(productBo.getId());
      wmsProductOssList.forEach(item->{
        Boolean inTable = false;
        for (WmsProductOss oss : productOss) {
          if (item.getOssId().equals(oss.getOssId())){
            inTable = true;
          }
        }
        if (!inTable){
          //数据库中不存在的值，删除
          ossService.deleteByBo(item);
        }
      });
    productOss.forEach(item->{
      Boolean inTable = false;
      for (WmsProductOss wmsProductOss : wmsProductOssList) {
        if (item.getOssId().equals(wmsProductOss.getOssId())){
          inTable = true;
        }
      }
      if (!inTable) {
        //数据库中不存在的值，新增
        ossService.insertByBo(item);
      }
    });
  }

  /**
   * 保存前的数据校验
   */
  private void validEntityBeforeSave(WmsProduct entity) {
    //TODO 做一些数据校验,如唯一约束
  }

  /**
   * 批量删除产品管理
   */
  public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
    if (isValid) {
      //TODO 做一些业务上的校验,判断是否需要校验
    }
    return baseMapper.deleteBatchIds(ids) > 0;
  }

  /**
   * 商城pc端 查询产品
   */
  public WmsProduct getGoodById(Long id) {
    List<WmsProduct> wmsProductList = baseMapper.productInfo(id);
    if (wmsProductList.size() == 0){
      return null;
    }
    // 按ID分组
    Map<Long, List<WmsProduct>> groupedById = wmsProductList.stream()
      .collect(Collectors.groupingBy(WmsProduct::getId));
    // 找到sku最小的WmsProduct对象
    WmsProduct resGood = wmsProductList.stream()
      .min(Comparator.comparing(WmsProduct::getSku))
      .orElse(new WmsProduct());
    // 获取具有相同ID的所有URL
    List<String> mainPicture = groupedById.get(resGood.getId()).stream()
      .map(WmsProduct::getUrl)
      .collect(Collectors.toList());
    // 设置resGood的mainPicture属性
    resGood.setMainPictures(mainPicture);

    // 提取attrValueName和attrValue
    List<String> attrValueNames = new ArrayList<>();
//    List<String> attrValues = new ArrayList<>();

    attrValueNames = Arrays.asList(wmsProductList.get(0).getAttrValueName().split("\\|"));

    //去除重复值
    List<WmsProduct> wmsProductListFilter = wmsProductList.stream()
      .collect(Collectors.toMap(
        WmsProduct::getId,  // 使用 id 作为键
        wmsProduct -> wmsProduct,  // 使用 WmsProduct 实例作为值
        (existing, replacement) -> existing))  // 如果键重复，保留第一个
      .values()
      .stream()
      .collect(Collectors.toList());

    //attrValueNames = {颜色，尺寸，产地}
/*    List<Spec> spec = new ArrayList<>();
    for (String attrValueName : attrValueNames) {
      int index = attrValueNames.indexOf(attrValueName);
      Spec spec1 = new Spec();
      List<Value> valueList = new ArrayList<>();
      spec1.setName(attrValueName);
      for (WmsProduct product : wmsProductListFilter) {
        attrValues = Arrays.asList(product.getAttrValue().split("\\|"));
        Value value = new Value();
        value.setName(attrValues.get(index));
        if (attrValueName.equals("颜色")){
          value.setPicture(product.getUrl());
        }
        boolean exists = false;
        if (spec1.getValues() !=null && spec1.getValues().size() > 0){
          exists = spec1.getValues().stream()
            .anyMatch(value1 -> value1.getName().equals(value.getName()));
        }
        if (!exists){
          valueList.add(value);
          spec1.setValues(valueList);
        }
      }
      spec.add(spec1);
    }
    resGood.setSpecs(spec);*/

    List<String> finalAttrValueNames = attrValueNames;
    List<Spec> specs = attrValueNames.stream()
      .map(attrValueName -> {
        Spec spec = new Spec();
        spec.setName(attrValueName);

        List<Value> values = wmsProductListFilter.stream()
          .map(product -> {
            List<String> attrValues = Arrays.asList(product.getAttrValue().split("\\|"));
            Value value = new Value();
            value.setName(attrValues.get(finalAttrValueNames.indexOf(attrValueName)));
            if (attrValueName.equals("颜色")) {
              value.setPicture(product.getUrl());
            }
            return value;
          })
          .collect(Collectors.toMap(
            Value::getName,
            value -> value,
            (existing, replacement) -> existing
          ))
          .values()
          .stream()
          .collect(Collectors.toList());

        spec.setValues(values);
        return spec;
      })
      .collect(Collectors.toList());
    resGood.setSpecs(specs);

/*    for (WmsProduct product : wmsProductListFilter){
      Sku sku = new Sku();
      sku.setId(product.getId());
      sku.setSkuCode(product.getSku());
      sku.setInventory(product.getInventory());
      sku.setPrice(product.getPrice());
      sku.setOldPrice(product.getOldPrice());
      List<SkuSpec> specs = new ArrayList<>();
      for (String attrValueName : attrValueNames){
        int index = attrValueNames.indexOf(attrValueName);
        attrValues = Arrays.asList(product.getAttrValue().split("\\|"));
        SkuSpec skuSpec = new SkuSpec();
        skuSpec.setName(attrValueName);
        skuSpec.setValueName(attrValues.get(index));
        specs.add(skuSpec);
      }
      sku.setSpecs(specs);
      if (resGood.getSkus() != null)
        resGood.getSkus().add(sku);
      else{
        List<Sku> skuList = new ArrayList<>();
        skuList.add(sku);
        resGood.setSkus(skuList);
      }
    }*/

    List<String> finalAttrValueNames1 = attrValueNames;
    List<Sku> skus = wmsProductListFilter.stream()
      .map(product -> {
        Sku sku = new Sku();
        sku.setId(product.getId());
        sku.setSkuCode(product.getSku());
        sku.setInventory(product.getInventory());
        sku.setPrice(product.getPrice());
        sku.setOldPrice(product.getOldPrice());

        List<SkuSpec> specs2 = finalAttrValueNames1.stream()
          .map(attrValueName -> {
            List<String> attrValues = Arrays.asList(product.getAttrValue().split("\\|"));
            SkuSpec skuSpec = new SkuSpec();
            skuSpec.setName(attrValueName);
            skuSpec.setValueName(attrValues.get(finalAttrValueNames1.indexOf(attrValueName)));
            return skuSpec;
          })
          .collect(Collectors.toList());

        sku.setSpecs(specs2);
        return sku;
      })
      .collect(Collectors.toList());

    if (resGood.getSkus() != null) {
      resGood.getSkus().addAll(skus);
    } else {
      resGood.setSkus(skus);
    }

    return resGood;
  }
}
